\documentclass[10pt,a4paper]{article}
\usepackage[latin1]{inputenc}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage[spanish,activeacute]{babel}
\usepackage[dvips]{graphicx}
\usepackage{lmodern}
%\usepackage{ve1batim}
\author{Grupo nº}
\title{Mandelzoom}
\date{22 de Septiembre de 2009}


\addtolength{\textwidth}{3cm}
\addtolength{\marginparsep}{4cm}
\setlength{\marginparwidth}{0cm}
\setlength{\marginparpush}{0cm}
\addtolength{\hoffset}{-1.5cm}
\begin{document}

\tableofcontents

\newpage
\begin{abstract}
En este trabajo pretendemos lograr graficar el fractal de Mandelbrot con zoom arbitrario. De esto se desprende que debemos implementar una aritm'etica tal que permita determinar la precisi'on, ya que esto no es posible utilizando tipos primitivos. Nuestra implementaci'on est'a desarrollada en base 10.
Nuestro objetivo es conocer si realmente es necesario utilizar un tipo propio que tenga precisi'on arbitraria, en detrimento de la velocidad de procesamiento ; o bien acotar el rango de precisiones posibles favoreciendo la performance (todo esto sin perder en calidad de im'agen).
Este trabajo fue realizado 'integramente en C++ y genera im'agenes en formato bmp.
\end{abstract}


\section{Introducci'on te'orica}

La aritm'etica dentro de una computadora es finita, debido a la caracter'istica intr'inseca de que posee capacidad de almacenamiento finita. En el caso particular de los n'umeros reales, que son densos, al poder representar solamente una cantidad acotada en general, se le suma el mismo problema entre dos n'umeros cualesquiera. Es decir que solamente se posee una precisi'on fija y acotada. Esto genera que si intentamos guardar un n'umero con mayor precisi'on que la permitida ser'a truncado y redondeada su 'ultima cifra.
Tambi'en es importante destacar que la forma de almacenamiento de n'umeros reales es mediante el formato de punto flotante y seg'un el est'andar de la IEEE 754. Es decir que se guardan dos caracter'isticas de cada n'umero para poder representarlo, la mantisa y el exponente (en punto flotante los reales se pueden escribir como mantisa$*$base$^{exponente}$, dentro de la mantisa est'a el signo y adem'as est'a acotada por la precisi'on), ya que como dentro de una computadora se almacena en binario, se considera impl'icitamente que se usa base 2. Justamente que se utilice binario internamente genera algunos conflictos en el traspaso base 10 $-$ base 2 $-$ base 10.
\newline
\newline
El conjunto de Mandelbrot es el m'as conocido de los conjuntos fractales, y el m'as estudiado. Se conoce as'i en honor al cient'ifico Benoit Mandelbrot, que investig'o sobre 'el en la d'ecada de los setenta del siglo XX.

Este conjunto se define as'i, en el plano complejo:
Sea c un n'umero complejo cualquiera. A partir de c, se construye una sucesi'on por inducci'on:
\begin{displaymath}
\left \{ \begin{matrix} z_0 & = & 0 \qquad \ & \mbox{(t'ermino inicial)} \qquad \\ z_{n+1} & = & z_n^2 + c & \mbox{(relaci'on de inducci'on)} \end{matrix} \right.
\end{displaymath}
Si esta sucesi'on queda acotada, entonces se dice que c pertenece al conjunto de Mandelbrot, y si no, queda excluido del mismo.

Por ejemplo, si c= 1 obtenemos la sucesi'on 0, 1, 2, 5, 26 que diverge. Como no est'a acotada, 1 no es un elemento del conjunto de Mandelbrot.

En cambio, si c =-1 obtenemos la sucesi'on 0, -1, 0, -1, que s'i es acotada, y por tanto, -1 s'i pertenece al conjunto de Mandelbrot.

A menudo se representa el conjunto mediante el algoritmo de tiempo de escape. En ese caso, los colores de los puntos que no pertenecen al conjunto indican la velocidad con la que diverge (tiende al infinito, en m'odulo) la sucesi'on correspondiente a dicho punto. 

Como no se puede calcular un sinf'in de valores, es preciso poner un l'imite y decidir que si los p primeros t'erminos de la sucesi'on est'an acotados entonces se considera que el punto pertenece al conjunto. Al aumentar el valor de p mejora la precisi'on de la imagen.


Por otra parte, se sabe que los puntos cuya distancia al origen es superior a 2, es decir, $x2 + y2 = 4$ no pertenecen al conjunto. Por lo tanto basta encontrar un solo t'ermino de la sucesi'on que verifique $|zn| > 2$ para estar seguro que c no est'a en el conjunto.



\section[Desarrollo]{Desarrollo}
Para poder realizar zoom tan potente como se desee en el fractal de Mandelbrot necesitamos tener una aritm'etica que tenga precisi'on arbitraria, es decir que pueda ser configurada seg'un la necesidad. La que nosotros hicimos es decimal, con lo cual consideramos que la base es 10 y que los d'igitos de la mantisa son  numeros entre 0 y 9. Nuestra estructura guarda la mantisa, el exponente y el signo. La mantisa es un arreglo de short, con un invariante que asegura que el elemento en la primera posici'on es distinto de cero siempre que el n'umero no sea 0 (lo cual ocurre nada m'as si en la mantisa hay solamente ceros y el exponente es cero), y que en cada posici'on puede haber n'umeros entre 0 y 9. Esto genera que tengamos que verificar esas condiciones cuando creamos o modificamos alg'un elemento.

La complejidad de la aritmetica est'a en las operaciones suma, resta y multiplicaci'on, que son utilizadas para hacer los c'alculos necesarios para poder graficar Mandelbrot. Tambi'en debimos implementar un m'etodo llamado razon que aproxima una divisi'on, devolviendo un entero. Esta operaci'on la tuvimos que realizar ya que nos sirve para hacer ciertos c'alculos que son vitales a la hora de graficar.

Implementamos la funci'on asegurar, con el objetivo de poder testear, ya que verifica que lo que imprime en pantalla el operador $<<$ (el cual fue sobrecargado) sea igual que el string que se le pasa como argumento.




\subsection{Implementacion de la aritm'etica de punto flotante}
Denominamos $"$BigFloat$"$ a nuestra implementaci'on de aritm'etica de punto flotante.
Al implementar las operaciones b'asicas de suma (la resta es un caso particular de 'esta) y multiplicaci'on surgieron algunos planteos respecto de la prioridad que deb'iamos definir entre eficacia en la \emph{implementaci'on} (tiempo y espacio consumidos en ejecucion) y libertad en la elecci'on de la \emph{precisi'on} para el usuario del programa.

En un primer momento optamos por priorizar la segunda en detrimento de la primera, dado que no conoc'iamos el alcance que ten'ian los valores de precision que est'abamos manejando y consideramos poner toda la implementaci'on a su servicio.
Sin embargo al ejecutar Mandelbrot con esta primera implementaci'on de BigFloat (BigFloat/algo1) observamos una importante deficiencia en los tiempo de ejecuci'on, comparada con la misma ejecuci'on hecha con double (o sea usando el tipo primitivo) en primera instancia, en particular en el algoritmo de la multiplicaci'on. Notamos entonces que pod'iamos mejorar mucho la performance (casi reduciendo los tiempos a la mitad) si encontrabamos una cota superior para la precisi'on y supeditabamos el programa a ella (a esto le llamamos luego BigFloat/algo2).

El algoritmo de la suma por su parte no presentaba esta particularidad dado que no existen las sumas parciales m'as que de los dos digitos sumados (con lo cual la suma nos qued'o identica para Bigfloat/algo1 y Bigfloat/algo2).
\newline
Al comprobar que la cota superior encontrada era v'alida, y considerando que satisfac'ia por mucho los objetivos que busc'abamos, decidimos reimplementar este algortimo, encontrando los resultados esperados.
\newline
La diferencia fundamenteal de los 2 algoritmos es la siguiente:
El Algoritmo1 (en bigfloat.cpp) realiza el producto cruzado de cada digito de un multiplicando con cada digito del otro, sumando en la posicion indicada en un array auxiliar $"acumulador"$ el resultado del mismo y en cada una de estas instancias realiza el m'odulo y sumando el carry a la siguiente posici'on (si carry = 0 la siguiente posicion queda igual).De esta forma nos aseguramos que cualquiera sea el resultado de las sumas parciales del producto para cualquier posici'on del array acumulador era soportada por el tipo short del array.

Hagamos un ejemplo sencillo mostrando los resultados parciales del array auxiliar $"acum"$, 'este se construye con mantisa del doble (2$*$n) que los multiplicandos: 

                      a=         1234 

                      b=         5678  $*$=  

en cada iteracion se realiza el producto cruzado de los digitos $a[i] ,b[j]$, y se suma a la posicion correspondiente de acum: $acum[i+j]+=(a[i]*b[j])mod10$; luego a la siguiente posicion (recorremos de $>$ los indices del array, donde los digitos m'as significativos est'an en los indices mas bajos) se le suma el carry obteniendo, $acum[i+j-1]+=(a[i]*b[j])/10$  as'i estos pasos nos dejar'ian a nuestro acum de la siguiente forma:

Iteraciones 

8$*$4

 $acum[0,0,0,0,0,0,0+32] => acum[0,0,0,0,0+32/10,32mod10] => acum[0,0,0,0,0,0,3,2]$

8$*$3.. 

acum$[0,0,0,0,0,0,3+24,2] => acum[0,0,0,0,0,0+27/10,27mod10,2]$\\$=> acum[0,0,0,0,0,2,7,2]$

 etc..
 
7$*$4 .. 
 
 acum$[0,0,0,0,9,8,7+28,2] => acum[0,0,0,0,9,8,(35)mod10,2]$\\$=> acum[0,0,0,0,9,8+(35/10),5,2]$
 
 etc..
 
hasta el final =  $acum[0,7,0,0,6,6,5,2]$
 
 
De manera que al finalizar nuestras iteraciones, tenemos en acum (m'as el carry del 'ultimo y m'as significativo digito) el resultado de la multiplicaci'on de las mantisas.
 
El Algoritmo2 (en $bigfloatrapido.cpp$ o "r'apido") toma la idea de que siempre existe una cota superior para el resultado de sumar cada columna de los subproductos de una multiplicacion, o sea el max (sumacolumna "i"), y este m'aximo depende de la longitud "n" (en d'igitos, en nuestro caso mantisa) de los multiplicandos (en nuestro caso siempre tienen la misma longitud, o sea precision) y del resultado de hacer el producto de los 2 digitos m'as grandes, en nuestro caso de 81 (9$*$9).
Veamos el mismo ejemplo de multiplicaci'on

8$*$4

$acum[0,0,0,0,0,0,0,0+32]$ 

8$*$3.. 

$acum[0,0,0,0,0,0,24,32]$ 
 
 etc hasta terminar con este digito

luego 7$*$4
 
 $acum[0,0,0,0,8,16,24+28,32]$ 

7$*$3 ..

$acum[0,0,0,0,8,16+21,24+28,32]$ 

..hasta el final donde nos queda  $acum[5,16,34,60,61,52,32]$

Luego recorremos el $acum[]$ y barremos con los carrys (tomando mod10 y $/10$) qued'andonos el resultado

$acum[0,7,0,0,6,6,5,2]$


Calculando la complejidad de los algortimos en funci'on de operaciones elementales obtuvimos que tomando $n$ como el tama'no del array de la mantisa 
tenemos 7$n^{2}$ para el Algoritmo1 contra $n^{2}$+6n para el Algoritmo2 y si bien ambos est'an en el orden $O(n^{2})$ las constantes de proporci'on son considerables y de hecho en la pr'actica quedo demostrado.    

Veamos como encontramos la cota, observando el esquema de sumas parciales que nos queda en el algoritmo tradicional de la multiplicaci'on (filas de n'umeros corridos en un digito a izquierda respecto de la fila anterior), nos dimos cuenta que la columna que mas digitos puede sumar es la columna del medio o sea si tenemos acum[0..$(2*n-1)$] la columna en cuesti'on es la (n-1), y la cantidad de digitos que suma son exactamente n, y el max de cada digito (de un producto parcial) es $9*9=81$ en nuestro caso, con lo cual ya tenemos una base de $81*n$.

Sin embargo la cota puede a'un ser mas grande todav'ia, teniendo en cuenta que podemos traer un acarreo de los d'igitos anteriores, o sea de las columnas [n..$2*n-1$].Buscamos entonces una f'ormula cerrada para esto y hallamos la siguiente:
\\
\\

\begin{displaymath}
cota=81*n+\sum_{i=1{n}} {(n-i)81/10^{i}}
\end{displaymath}
y desarrollando...
\begin{displaymath}
81*n+\sum_{i=1{n}} {(n-i)81/10^{i}} = 81*n +81*\sum_{i=1{n}} {(n-i)/10^{i}}
\end{displaymath}
acotando 1$/$10$^i$ <= 1$/$10.. y por la f'ormula cerrada de la sumatoria de (n-i) ..
\begin{displaymath}
 = 81*n +81*\sum_{i=1{n}} {(n-i)/10^{i}} <= 81*n+(81*(n(n-1))/2)*1/10 = 
\end{displaymath}
acotando una vez mas ...
\begin{displaymath}
 =(81/20)*(20n+n^{2}-n) <= 76n+81/20n^{2}   
\end{displaymath}

Luego calculando el m'aximo n posible suponiendo que usamos arrays de short para la mantisa, y 'este representa como m'aximo hasta el 32.767 nos queda
\begin{displaymath}
 76n+81/20n^{2} = 32.767  
\end{displaymath}
\newline

Lo que nos da un n aproximado de 102; con lo que podemos decir que el Algoritmo2 nos sirve para multiplicar n'umeros con precisiones iguales de hasta 100 digitos de mantisa.
\newline

\subsection{Modos de ingreso par'ametros de usuario}
   Una vez resuelta nuestra implementaci'on de Aritm'etica de punto flotante o $"$BigFloat$"$, nos enfrentamos a una nueva problem'atica respecto de como generar los gr'aficos del output, es decir en funci'on de que par'ametros de entrada. Luego de encontrar dos diferentes e interesantes modos (a los que llamamos $"$modo escala double$"$ y $"$modo escala BigFloat$"$) decidimos ofrecerle al usuario ambas posibilidades para obtener los graficos de Mandelbrot. Estos modos son los que explicamos a continuaci'on.
      Cuando uno quiere generar un gr'afico de una funci'on sobre cierta regi'on del plano (digamos desde x1 hasta x2, desde y1 hasta y2) hay que decidir tambi'en a qu'e escala deseamos hacerlo. Por ejemplo si en x queremos abarcar desde -2 hasta 2 y en y desde 0 hasta 2 podr'iamos representar una unidad por p'ixel (en cuyo caso el dibujo resultante ser'ia de 4x2 pixeles) o bien una cent'esima de unidad por p'ixel (lo que arrojar'ia un gr'afico de 400x200).
    Pensemos por simplicidad en la coordenada x; llamemos $'xRes'$ (por resoluci'on en x) al ancho en pixeles del dibujo resultante (o equivalentemente a la cantidad de columnas barridas en la discretizaci'on) y $'xScale'$ a la cantidad l'ogica representada por cada columna de pixeles. Suponiendo x2 $>$ x1 tenemos la f'ormula

xScale = (x2$-$x1) / xRes    
 
    o lo que es lo mismo
    
xRes =  (x2$-$x1) / xScale


    Como se ve (y como es intuitivo) dado x1 y x2 basta con determinar una sola de las otras dos variables para poder calcular la tercera. Por lo tanto, hay dos formas distintas en las que un usuario puede especificar el dibujo que quiere generar:

a) estableciendo las coordenadas y la resoluci'on (y el programa deduce la escala)
b) estableciendo las coordenadas y la escala (y el programa deduce la resoluci'on)

    A priori nos pareci'o m'as interesante la primera variante, dado que el usuario probablemente est'e m'as interesado en fijar el tama'no f'isico de lo que quiere ver y no en su precisi'on l'ogica. Sin embargo, de implementar esta variante, nuestro programa deber'ia calcular la escala como $(x2-x1) / xRes$, lo cual es un problema porque nos obliga a implementar la divisi'on en precisi'on arbitraria, lo cual sab'iamos que es dificultoso. En cambio, la segunda variante es un poco m'as sencilla de implementar pues se puede empezar a barrer el plano con un acumulador puesto en x1, ir sum'andole xScale en cada columna del barrido y terminar cuando ese acumulador supere x2. Claro que, en este caso, el usuario deber'a ponerse a hacer cuentas para pasarle al programa una escala que genere un dibujo con tama'no razonable.

    Fue entonces cuando nos hicimos la siguiente pregunta: ?`Ser'a necesario barrer el plano con precisi'on arbitraria? ?`No ser'a suficiente barrerlo de a saltos (es decir, con una escala) de precisi'on double (o long double) y usar la precisi'on arbitraria solamente para mejorar el c'alculo de la sucesi'on de Mandelbrot a lo largo de las iteraciones?
    
Luego de analizarlo un poco nos pareci'o que s'i, que barrer el plano de a saltos con precisi'on double ser'ia m'as que suficiente para niveles de zoom razonables.
    
Supongamos que double tiene 15 d'igitos decimales de mantisa y que corremos el programa usando 100 d'igitos para la precisi'on arbitraria; entonces, por m'as que la escala sea double, cuando hagamos la primera iteraci'on en la sucesi'on de mandelbrot (que es cuadr'atica) necesitaremos aproximadamente 30 d'igitos decimales para almacenar el resultado con fidelidad. As'i, luego de unas pocas iteraciones se agotar'a incluso la precisi'on arbitraria, por lo tanto resulta evidente que, pese a usar precisi'on double para el barrido, se aprovecha mucho la precisi'on extra cuando se realizan las iteraciones, que en la pr'actica son muchas.

    Por eso implementamos dos modos distintos para la lectura de los par'ametros del usuario: 
- modo de escala double: el usuario indica las coordenadas, que son interpretadas como double's, y la resoluci'on (que es interpretado como el m'aximo entre el ancho y el alto en pixeles del dibujo que se generar'a). El programa entonces calcula la escala, con precisi'on double, y convierte los par'ametros double a precisi'on arbitraria.
- modo de escala con precisi'on arbitraria: en este modo las coordenadas que ingresa el usuario son interpretadas como BigFloat's (nuestra implementaci'on de precisi'on arbitraria) y, en lugar de indicar la resoluci'on que se desea, se indica la escala que se usar'a. 
Este modo tiene la incomodidad de tener que calcular la escala a mano, pero la ventaja de poder barrer regiones especificadas con mayor precisi'on.


\newpage 
\section{Experimentaci'on}
\subsection{Implementaci'on de la aritm'etica}
Realizamos corridas de diferentes Mandelzooms con los algoritmos BigF/algo1, BigF/algo2 y con Mandelzoom implementado con el tipo primitivo Double, con el fin de observar la performance (en cuanto a tiempo) en estos tres casos y compararla.  

\subsection{Efectos de la variaci'on de par'ametros }
Realizamos zooms de Mandelbrots recursivamente, esto quiere decir a la primer im'agen obtenida (de 4x4 con coordenadas -2,2,-2,2 ) le aplicamos zoom a una replica casi identica que aparece sobre el eje x, hacia el lado izquierdo, tal como se ve en la siguiente im'agen. 

\begin{center}
\includegraphics[width=8cm,height=8cm,]{initial}
\end{center}

Haciendo esto para una Resolucion de imagen fija (400x400 pixeles), lo que buscamos era observar el comportamiento de Mandelzoom propiamente dicho, es decir c'omo se observaba la im'agen para escalas cada vez m'as peque\~nas.  

Adem'as, sobre cada uno de los Mandelzooms hechos (o sea sobre cada Escala y Resoluci'on fijas), fuimos aumentando de una manera gradual-significativa (a nivel visual) la cantidad de iteraciones con la que calculamos Mandelbrot para cada pixel. As'i corrimos con 100-300-900-2700 iteraciones para observar el comportamiento del mismo para cada Escala en cuesti'on. 

Por otra parte todos estos ensayos, los realizamos con el tipo primitivo Double y con BigFloat para testear diferencias (aumentando considerablemente la precisi'on, es decir la mantisa, en el caso de BigFloat). 

Sin embargo, dado que en los ensayos hasta aqu'i realizados no encontramos diferencias visuales a la hora de aumentar la precisi'on en BigFloat, decidimos aumentar a'un mas la escala para intentar hacer visible limitaci'on que tendr'iamos con el tipo Double y su mejora aplicando BigFloat con mayor precision en la implementaci'on del zoom. 





\newpage
\section{Resultados}

\subsection{Implementaci'on de la aritm'etica}


El siguiente gr'afico nos muestra los tiempos de ejecuci'on en funci'on de los diferentes inputs(logx, x es un n'umero cualquiera solo para diferenciar las corridas) para el mandelzoom realizado con los algoritmos BigF/algo1, BigF/algo2 y el tipo primitivo Double.

Observamos claramente que los tiempos de corrida con el tipo primitivo double son mucho menores que los otros dos implementados por nosotros BigF/algo1 y BigF/algo2, tambi'en que tal como lo esper'abamos el BigF/algo2 redujo en un 25\% aproximado el tiempo de corrida del BigF/algo1.

\includegraphics[width=10cm,height=9cm]{tablatiempos}

Los inputs de los Mandelzooms son los siguientes (el cuadrado rojo indica el zoom realizado en el Mandelzoom siguiente, a derecha):
\newline

\includegraphics[width=3cm,height=3cm]{log8} \textsf{\tiny\emph{log8}}
\includegraphics[width=3cm,height=3cm]{log13} \textsf{\tiny\emph{log13}}
\includegraphics[width=3cm,height=3cm]{log16} \textsf{\tiny\emph{log16}}
\newline

logx: modo x1 x2 y1 y2 Resoluci'on iteraciones  (precisi'on en el caso de BigF usamos 15 de mantisa para igualar la precisi'on de un double)

log8 : dbl -2 2 -2 2 200 100 

log13: dbl 0.25 0.5 0 0.25 200 200  

log16: dbl 0.3  0.30625  0.01875 0.025 200 1000 

\newpage
\subsection{Efectos de la variaci'on de par'ametros }

En la siguiente secuencia de im'agenes se grafica el fractal de Mandelbrot relacionando la Escala (Zoom) con la cantidad de Iteraciones. 

Los cuadrados en rojo indican la iteraci'on (zoom) que se realiza en la Escala siguiente, adem'as en cada fila tenemos las coordenadas x1,x2,y1,y2 correspondientes al zoom realizado. 


\begin{center}
\includegraphics[width=13cm,height=13cm]{mandelbrots} 
\newline
\textsf{\tiny\emph{Secuencia de Mandelbrots}}
\end{center}


Con estos resultados pudimos observar la necesidad de mantener una relaci'on directa entre Escala y cantidad de Iteraciones para mantener la nitidez de la im'agen.

\newpage

Esto quiere decir que a medida que incrementamos la Escala, si dejamos fija la cantidad de Iteraciones, observamos una mayor densidad de puntos (cada uno asociado a un pixel) que convergen a la misma velocidad, o sea que necesitamos aumentar la cantidad de Iteraciones para diferenciar mejor las velocidades de convergencia y lograr as'i una mejor visualizaci'on de los Mandelbroots.    
\newline
Al tomar las im'agenes de este ensayo, observamos que no hay mejora visual significativa entre las corridas con Double (precisi'on de 15 d'igitos decimales aprox) y con BigFloat configurando la precisi'on en 30 digitos decimales (es decir que en el segundo caso la precisi'on es el doble que en el primero).
\newline
Las siguientes im'agenes corresponden a un zoom hecho a escala 1e-07 y 900 iteraciones, y nos muestran lo dicho anteriormente.
\newline

\includegraphics[width=3cm,height=3cm]{double} 
\includegraphics[width=3cm,height=3cm]{bigF} 
\newline
\hspace{1 cm}\textsf{\tiny\emph{double}}
\hspace{2 cm}\textsf{\tiny\emph{bigFloat}}
\newline

Es por ello que decidimos seguir explorando, es decir realizando zooms a escalas cada vez m'as peque'nas.
Pudimos observar que las diferencias entre double y BigFloat segu'ian siendo no significativas, solamente al observar muy detalladamente se puede notar que los gr'aficos no son exactamente iguales, sino que hay algunas manchas m'as marcadas que otras y algunas diferencias entre algunas regiones en cuanto a nitidez, lo que revela resultados de coloraci'on distinta para mismos pixeles con uno y otro algoritmo, o sea diferentes resultados del calculo de Mandelbrot, dados por la 'unica diferencia que tienen los algoritmos que es el uso de las diferentes aritm'eticas.

Suponemos que si pudieramos seguir haciendo zoom en tiempos razonables, lograr'iamos distinguir una diferencia de calidad de im'agen a favor de BigFloat.

Las siguientes im'agenes son algunas de los resultados de estas 'ultimas experimentaciones.
\newline

\includegraphics[width=7cm,height=7cm]{072000_x200double}
\includegraphics[width=7cm,height=7cm]{072000_x200bigF}

\textsf{\tiny\emph{double:   img  200x200 , Escala:7.5x10$^{-10}$ , Iteraciones:2000 }}
\hspace{2 cm}\textsf{\tiny\emph{   bigFloat:  img  200x200 ,Escala:7.5x10$^{-10}$, Iteraciones:2000 }}
\newline
\newpage

\includegraphics[width=7cm,height=7cm]{102000x200double} 
\includegraphics[width=7cm,height=7cm]{102000x200bigF}

\textsf{\tiny\emph{double:  img 200x200 , Escala=1x10$^{-12}$ , Iteraciones:2000}}
\hspace{2 cm}\textsf{\tiny\emph{ bigFloat img 200x200 , Escala=1x10$^{-12}$ ,Iteraciones:2000}}
\newline

Por 'ultimo mostramos una tabla que describe la relaci'on que hallamos entre la cantidad de Iteraciones y la  Escala. A medida que aumenta el zoom o disminuye la Escala (hacia derecha sobre las x), aumenta la cantidad de Iteraciones. A partir de escalas del orden de 1e-14 aproximadamente, las iteraciones necesarias se acrecientan mucho, lo cual hace que nuestro BigFloat pierda efectividad en t'erminos de tiempo.
\newline

\includegraphics[width=15cm,height=10cm,scale=0.5]{tablaEscIter} 

\hspace{3 cm}\textsf{\tiny\emph{ Iteraciones necesarias en funci'on de la escala}}

\newpage
\section{Discusi'on}

La diferencia entre la implementaci'on de prueba que hicimos con long double y la que utiliza un tipo especial que permite utilizar precisi'on arbitraria (llamado BigFloat), es notable en cuanto a tiempo. Esto creemos que se debe a que el tipo long double realiza las operaciones suma, resta y multiplicaci'on por hardware, en cambio BigFloat lo hace por software. A esto tambi'en hay que sumarle el manejo de memoria por parte de la clase, lo cual tambi'en hace m'as lento al proceso de c'alculo.
\newline

En los gr'aficos que comparan la calidad de im'agen con respecto a las iteraciones, se puede notar que mientras mayor es el n'umero de iteraciones mejor es la calidad. Tambi'en sucede que mientras m'as zoom se realiza es mayor la cantidad de iteraciones necesarias para mantener la misma calidad de im'agen. Esto ocurre debido a que al utilizar un zoom mayor requiere m'as cantidad de operaciones determinar si converge o no cierto punto. Es por ello que cuando no se realizan las necesarias ni siquiera alcanza a verse la forma t'ipica del fractal.
\newline

Con respecto a las implementaciones realizadas, como se pudo ver en Resultados, no logramos llegar a encontrar una diferencia importante en la calidad entre la utilizaci'on de Double o de BigFloat. Sin embargo, las peque'nas diferencias que encontramos al hacer el zoom m'as potente que tarde un tiempo razonable, nos hacen pensar que si continu'aramos en esa l'inea lograr'iamos llegar a un punto en el que se note la mayor calidad que puede proveer BigFloat, gracias a su caracter'istica distintiva, la precisi'on arbitraria. 
\newline

Algo que nos qued'o pendiente es que en realidad pretend'iamos optimizar el c'odigo de BigFloat, con el objetivo de disminuir el tiempo de ejecuci'on de sus operaciones, lo cual nos permitir'ia realizar un mayor zoom en tiempo razonable. La dificultad de esto 'ultimo es que a escalas muy peque'nas, las corridas exigen una gran cantidad de iteraciones (lo cual queda claro en la secci'on Resultados), pesando cada vez m'as el costo de las operaciones de BigFloat.
\newline

Otra pregunta que tampoco pudimos responder, debido a que no llegamos a tiempo, es si habr'ia una diferencia en cuanto a rendimiento al implementar BigFloat en base 2, en vez de en base 10. Optamos por lo segundo en un primer momento por una cuesti'on de claridad en el c'odigo, pero luego nos surgi'o esta duda, la cual lamentablemente qued'o en el tintero.


\newpage
\section{Conclusiones}

Primero, es importante decir que creemos que hemos logrado el objetivo que se planteaba con este trabajo, poder lograr graficar el fractal de Mandelbrot y hacer todo el zoom que se desee. Para esto, como ya fue dicho, tuvimos ditintas ideas para la implementaci'on. Lo que nos parece que ser'ia lo mejor es utilizar la implementaci'on hecha con Double, hasta el punto en que comienza a notarse en la calidad de las im'agenes que la precisi'on de este tipo es menor que la necesaria. A partir de ese momento habr'ia que comenzar a usar BigFloat, ya que permite configurar la presici'on y se puede ir aumentando seg'un el caso. La desventaja es que los tiempos de ejecuci'on en este caso son mucho mayores, as'i que lo mejor ser'ia utilizarlo solamente cuando sea absolutamente necesario. Igualmente creemos que es posible mejorar este tipo, de forma tal que se logre maximizar su rendimiento.
\newline

Nuestra conclusi'on final sobre el trabajo realizado es que para que sea determinante el poder setear la precisi'on hay que hacer un zoom demasiado potente. Tratamos de llegar utilizando long double a un lugar tal que no nos alcance la precisi'on de este tipo primitivo de C++. Lo que descubrimos es que hay que profundizar demasiado en el gr'afico para que sea necesario utilizar nuestro tipo (al cual llamamos BigFloat), ya que aumentando la cantidad de iteraciones se compensa la falta de precisi'on. De hecho, aunque lo intentamos en reiteradas ocaciones, no llegamos a encontrar lugar alguno en que tengamos que utilizar BigFloat en vez de long double para lograr que se vea n'itido el fractal de Mandelbrot (lo que hicimos fue ir aumentando la cantidad de iteraciones, como ya hemos explicado anteriormente).
\newpage
\section{Ap'endice}
\begin{centering}
\bf Laboratorio de M\'etodos Num\'ericos - Segundo cuatrimestre 2009 \\
\bf Trabajo Pr\'actico N\'umero 1: Mandelzoom \\
\end{centering}

\vskip 25pt
\hrule
\vskip 11pt

El \emph{conjunto de Mandelbrot} es uno de los objetos m\'as intrigantes
sobre el plano complejo, cuya frontera forma una figura fractal.
El objetivo del trabajo pr\'actico es implementar un programa que permita
realizar un zoom arbitrariamente grande sobre el conjunto de Mandelbrot,
utilizando para esto aritm\'etica de punto flotante de precisi\'on arbitraria.

Para cada $c\in\mathbb{C}$, sea $p_c:\mathbb{C}\to\mathbb{C}$ el polinomio definido
por $p(z) = z^2 + c$. Para cada complejo $c\in\mathbb{C}$, consideremos la secuencia
$0$, $p_c(0)$, $p_c(p_c(0))$, $p_c(p_c(p_c(0)))$, $\dots$ obtenida al iterar $p_c(z)$ comenzando
por $z=0$. El conjunto de Mandelbrot $M$ se define como el conjunto de puntos $c$ tales
que la secuencia anterior no escapa hacia el infinito. En particular, se puede probar que
\begin{displaymath}
M \ =\ \{ c\in\mathbb{C}: |p^n_c(0)| \le 2 \hbox{ para todo } n\in\mathbb{N} \}.
\end{displaymath}
El trabajo pr\'actico consiste en implementar un programa que genere im\'agenes
del conjunto de Mandelbrot con zoom arbitrariamente grande, utilizando una
implementaci\'on de la a\-rit\-m\'e\-ti\-ca de punto flotante binaria con precisi\'on
arbitraria. La implementaci\'on de esta a\-rit\-m\'e\-ti\-ca debe estar a cargo del grupo,
y no se pueden utilizar bibliotecas para este punto de la implementaci\'on.

Como funcionalidad m\'\i nima, el programa implementado debe tomar como datos de
entrada la regi\'on del plano complejo que se desea graficar y la precisi\'on de
la aritm\'etica de punto flotante deseada para los c\'alculos. Para generar la imagen, se
deben ``barrer'' los puntos de una discretizaci\'on adecuada de la regi\'on
a graficar, y para cada punto $c$ de la discretizaci\'on, decidir si la secuencia asociada
con el punto $c$ escapa hacia el infinito o se mantiene acotada. No es necesario
que el programa tenga una interfaz gr\'afica, sino que se pueden generar las
im\'agenes en archivos, tomando previamente los par\'ametros de la imagen y de la
aritm\'etica por l\'\i nea de comandos. En caso de que el grupo decida escribir
un archivo con la imagen generada, se pueden usar bibliotecas para manejar archivos
de im\'agenes.

El informe debe contener una descripci\'on detallada de las distintas
alternativas que el grupo haya considerado para la implementaci\'on de la
aritm\'etica de punto flotante con precisi\'on arbitraria, junto
con una discusi\'on de estas alternativas que justifique la opci\'on
implementada. Por otra parte, se debe incluir en la secci\'on correspondiente
el c\'odigo que implementa esta aritm\'etica, junto con todos los comentarios
y decisiones relevantes acerca de esta implementaci\'on.

El grupo que genere las im\'agenes m\'as impactantes del conjunto de Mandelbrot
se har\'a acreedor a un premio en met\'alico. Para esto, recomendamos explorar
las regiones cercanas al borde del conjunto.

\vskip 15pt

\hrule

\vskip 11pt

Fecha de entrega: Mi\'ercoles 23/9


\newpage
\section{Referencias}
\begin{itemize}
\item es.wikipedia.org
\item en.wikipedia.org
\item www.cppreference.com
\item The C++ Programming Lenguage de Bjarne Stroustrup
\item The not so short introduction to Latex
\end{itemize}

\end{document}